package com.utilities.parsers;

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import com.utilities.parsers.ContigParser.ParseAllContigsFileParser;
import com.utilities.parsers.ContigParser.ParseEvents;
import com.utilities.parsers.ContigParser.ParseListener;

public class ContigStats extends ParseListener {

	private double contigCount = 0;
	private double totalContigLength = 0;
	private double numberOfReads = 0;
	private boolean makeScaffold = false;
	private String scaffoldOutFile = null;
	private String scaffoldInFile = null;
	private FileWriter fw = null;
	private StringBuffer buffer = new StringBuffer();
	private int count;
	private String scaffoldName = null;

	public ContigStats(boolean makeScaffold, String scaffoldInFile, String scaffoldOutFile, String scaffoldName)
	{
		this.scaffoldOutFile = scaffoldOutFile;
		this.scaffoldInFile = scaffoldInFile;
		this.makeScaffold = makeScaffold;
		this.scaffoldName = scaffoldName;
	}
	public static void main(String[] args) throws Exception
	{
		ContigStats contigStats = new ContigStats(true, args[0], args[1], args[2]);
		contigStats.run();
	}

	public void run() throws IOException
	{
		fw = new FileWriter(new File(scaffoldOutFile));
		ParseAllContigsFileParser allContigsFileParser = 
			new ParseAllContigsFileParser();
		allContigsFileParser.addListener(this);
		allContigsFileParser.parse(new FileReader(scaffoldInFile));
	}

	public double getContigCount() {
		return contigCount;
	}
	public double getTotalContigLength() {
		return totalContigLength;
	}
	public double getNumberOfReads() {
		return numberOfReads;
	}
	@Override
	public void handleEvent(ParseEvents event) {
		try
		{
			switch((ParseEvents.EventTypes)event.getEventType())
			{
			case docStarted:
				fw.write(">"+ scaffoldName+ "\n"); break;
			case contigStarted: 
			{
				this.contigCount++;
				String readLine = (String)event.getSource();
				String[] params = readLine.replaceAll("\\b\\s{2,}\\b", " ").split(" ");
				if (params.length > 1)
				{
					double temp = this.totalContigLength + 
					(Double.parseDouble(params[1].split("=")[1].trim()));
					double temp2 = this.numberOfReads + 
					(Double.parseDouble(params[2].split("=")[1].trim()));
					if (temp < this.totalContigLength || temp2 < this.numberOfReads)
					{
						System.err.println("roll over");
						System.exit(1);
					}
					else
					{
						this.totalContigLength = temp;
						this.numberOfReads = temp;
					}
				}
				break;
			}
			case seqread :
			{
				if (makeScaffold)
				{
					String str = ((String)event.getSource()).trim();
					writeToBuffer(str,str.length());
					break;
				}

			}
			case docEnded : 
			{
				if (makeScaffold)
				{
					write(); fw.close(); break;
				}
				break;
			}
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
			System.exit(1);
		}
	}

	private void writeToBuffer(String str, int i) throws Exception 
	{
		if (str == null)
		{
			for (int j = 0 ; j < i ; j++)
			{
				buffer .append('N');
			}
		}
		else
		{
			buffer.append(str);
		}

		if (buffer.length() > 500)
		{
			write();
		}
	}

	private void write() throws Exception
	{
		for (int i = 0 ; i<buffer.length() ; i++)
		{
			fw.append(buffer.charAt(i));
			count++;
			if (count%60 == 0)
			{
				fw.append("\n");
			}
		}
		buffer = new StringBuffer();
		fw.flush();
	}
}
